package com.github.maojx0630.easy.translate;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.github.maojx0630.easy.translate.translate.TranslateHandle;
import com.github.maojx0630.easy.translate.translate.impl.dict.TranslateField;
import com.github.maojx0630.easy.translate.cache.ClassCacheDto;
import com.github.maojx0630.easy.translate.cache.ClassFieldCache;
import com.github.maojx0630.easy.translate.translate.impl.dict.ValueCache;
import com.github.maojx0630.easy.translate.json.ObjectToJsonObject;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author 毛家兴
 * @since 2024-01-31 14:35
 */
@Slf4j
@AllArgsConstructor
public class TranslateUtil {

  private ObjectToJsonObject toJson;

  public Object translate(Object o) {
    if (null == o) {
      return null;
    }
    ClassCacheDto.FieldType fieldType = ClassFieldCache.getClassType(o.getClass());
    if (fieldType != null) {
      switch (fieldType) {
        case ARRAY:
          List<Object> list = new ArrayList<>();
          for (Object next : (Iterable<?>) o) {
            list.add(translate(next));
          }
          return list;
        case PAGE:
          Map<String,Object> json = toJson.toObj(o);
          if (json == null) {
            return o;
          }
          Field field = ClassFieldCache.getField(o.getClass());
          if (field != null) {
            Object fieldValue = ReflectUtil.getFieldValue(o, field);
            json.put(field.getName(), translate(fieldValue));
          }
          return json;
      }
    }

    // 如果不能转为json对象就直接返回

    List<ClassCacheDto<?>> list = ClassFieldCache.getClassField(o.getClass());
    if (CollUtil.isNotEmpty(list)) {
      Map<String,Object> json = toJson.toObj(o);
      if (json == null) {
        return o;
      }
      for (ClassCacheDto<? extends Annotation> dto : list) {
        Object fieldValue = ReflectUtil.getFieldValue(o, dto.getField());
        if (null == fieldValue) {
          continue;
        }
        switch (dto.getFieldType()) {
          case DTO:
            json.put(dto.getField().getName(), translate(fieldValue));
            break;
          case FIELD:
            if (fieldValue instanceof String string) {
              setValueToJson(dto,string,json);
            }
            break;
          case ARRAY:
            List<Object> array = new ArrayList<>();
            if(fieldValue instanceof Iterable<?> iterable){
              for (Object next : iterable) {
                array.add(translate(next));
              }
              json.put(dto.getField().getName(), array);
            }
            break;
          case PAGE:
            Map<String,Object> page = toJson.toObj(fieldValue);
            if (page == null) {
              break;
            }
            Field field = ClassFieldCache.getField(fieldValue.getClass());
            if (field != null) {
              Object pageFieldValue = ReflectUtil.getFieldValue(fieldValue, field);
              json.put(field.getName(), translate(pageFieldValue));
            }
            break;
        }
      }
      return json;
    }
    return o;
  }

  private <A extends Annotation> void setValueToJson(ClassCacheDto<A> dto,String string,Map<String,Object> json){
    TranslateHandle<A> translateHandle = dto.getTranslateHandle();
    A translateField = dto.getTranslateField();
    Object translateValue = translateHandle.getTranslateValue(translateField, string, dto.getField());
    for (String name : translateHandle.getTranslateField(translateField, string, dto.getField())) {
      json.put(name, translateValue);
    }
  }
}
